﻿namespace MPNet6.Server;
public class MPSession
{
    private TcpClient? _TcpClient;
    private NetworkStream? _Stream;

    private object _Lock = new();

    private readonly List<string> _Msgs;
    private bool _IsOnce = false;


    public MPSession()
    {
        _Msgs = new();
    }
    public MPSession(string msgs)
    {
        _Msgs = string.IsNullOrEmpty(msgs) ? new() : msgs.Split('\r').ToList();
    }
    public void ConnectMore(TcpClient tcpClient, NetworkStream stream, byte connectType)
    {
        lock (_Lock)
        {
            //MPServer.Logger.LogInformation("Connect");
            //Thread.Sleep(10000);
            if (IsOnline(tcpClient, stream))
                return;


            bool success = true;

            if (_Msgs.Count == 0)
                success = stream.SendAndRecieve(connectType) > 0;
            else
            {
                while (_Msgs.Count > 0)
                {
                    if (stream.SendAndRecieve(_Msgs[0]) == 0)
                    {
                        success = false;
                        break;
                    }
                    _Msgs.RemoveAt(0);
                }
            }

            if (success)
            {
                _Stream = stream;
                _TcpClient = tcpClient;
                _IsOnce = false;
            }
            else
            {
                stream.Close();
                tcpClient.Close();
            }
        }
    }


    public void ConnectOnce(TcpClient tcpClient, NetworkStream stream)
    {
        lock (_Lock)
        {
            if (IsOnline(tcpClient, stream))
                return;
            if (stream.SendAndRecieve(MPConsts.ConnectSuccessOnce) > 0)
            {
                _IsOnce = true;
                _Stream = stream;
                _TcpClient = tcpClient;
                _Msgs.Clear();
            }
            else
            {
                stream.Close();
                tcpClient.Close();
            }
        }
    }

    public void ReconnectOnce(TcpClient tcpClient, NetworkStream stream)
    {


        lock (_Lock)
        {
            if (IsOnline(tcpClient, stream))
                return;


            if (_Msgs.Count == 0)
            {
                if (stream.SendAndRecieve(MPConsts.ReconnectSuccessOnce) > 0)
                {
                    _IsOnce = true;
                    _Stream = stream;
                    _TcpClient = tcpClient;
                }
                else
                {
                    stream.Close();
                    tcpClient.Close();
                }
            }
            else
            {
                if (stream.SendAndRecieve(_Msgs.Last()) > 0)
                    _Msgs.Clear();
                stream.Close();
                tcpClient.Close();
            }
        }
    }
    public void SendMessage(string msg)
    {
        lock (_Lock)
        {
            if (_Stream != null)
            {
                switch (_Stream.SendAndRecieve($"\t{msg}"))
                {
                    case 0://发送失败
                        SaveMsg(msg);
                        _Stream?.Close();
                        _TcpClient?.Close();
                        _Stream = null;
                        break;
                    case 2://Once发送成功
                        _Stream?.Close();
                        _TcpClient?.Close();
                        break;

                }
            }
            else
                SaveMsg(msg);
        }
    }


    public string Stop()
    {
        if (_Stream != null)
        {
            lock (_Lock)
            {
                _Stream?.Close();
                _TcpClient?.Close();
            }
        }
        return string.Join('\r', _Msgs);
    }


    private void SaveMsg(string msg)
    {
        if (_IsOnce)
        {
            _Msgs.Clear();
            _Msgs.Add(msg);
        }
        else
        {
            if (_Msgs.Count == 0 || _Msgs[_Msgs.Count - 1].Length + msg.Length > MPServer.SendBufferSize - 2)
                _Msgs.Add(msg);
            else
                _Msgs[_Msgs.Count - 1] += "\t" + msg;
        }

    }

    private bool IsOnline(TcpClient tcpClient, NetworkStream stream)
    {
        if (_Stream is not null && _Stream.SendAndRecieve(MPConsts.Echo) > 0)
        {
            stream.SendAndRecieve($"{MPConsts.Failure}Other client that used this id is online.");
            stream.Close();
            tcpClient.Close();
            return true;

        }
        else
        {
            _Stream?.Close();
            _TcpClient?.Close();
            _Stream = null;
            return false;
        }

    }
    public string ClientInfo
    {
        get => _TcpClient?.Connected == true ? "Online " + (_TcpClient?.Client?.RemoteEndPoint?.ToString() ?? "") : "Offline";
    }

}

